home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 4
/
Apprentice-Release4.iso
/
Languages
/
PowerMacOberon 1.2
/
Dialogs
/
DialogAnalogClocks.Mod
(
.txt
)
< prev
next >
Wrap
Oberon Text
|
1995-06-30
|
8KB
|
199 lines
Syntax10.Scn.Fnt
Syntax10i.Scn.Fnt
StampElems
Alloc
11 Nov 94
Syntax10b.Scn.Fnt
MODULE DialogAnalogClocks;
(** Markus Knasm
ller 14 Sep 94 -
(* This sourcecode uses parts of ClockElems - gri 18.3.91 *)
IMPORT DialogClocks, DialogFrames, Dialogs, Display, In, Math, Oberon, Printer;
CONST
W* = 65; H* = W; Rmin = 12; Rdef = 8.2; black = 15;
TYPE
Item* = POINTER TO ItemDesc;
ItemDesc* = RECORD(DialogClocks.ItemDesc)
END;
VAR
sin, cos: ARRAY 60 OF REAL;
Line: PROCEDURE (f: Display.Frame; x1, y1, x2, y2, color, mode: INTEGER);
Circle: PROCEDURE (f: Display.Frame; x0, y0, r, color, mode: INTEGER);
PROCEDURE Min (x, y: INTEGER): INTEGER;
BEGIN IF x < y THEN RETURN x ELSE RETURN y END
END Min;
PROCEDURE Init;
VAR i: INTEGER;
BEGIN i := 0;
WHILE i < 60 DO
sin[i] := Math.sin (2 * Math.pi / 60 * i);
cos[i] := Math.cos (2 * Math.pi / 60 * i);
INC (i)
END
END Init;
PROCEDURE Format (time: LONGINT; VAR sec, min, hour, hourm: INTEGER);
BEGIN
hour := SHORT (time DIV 4096 MOD 32);
min := SHORT (time DIV 64 MOD 64);
sec := SHORT (time MOD 64);
hourm := (hour MOD 12) * 5 + min DIV 12
END Format;
(* graphics *)
PROCEDURE SCircle(f: Display.Frame; x0, y0, r, color, mode: INTEGER);
VAR x, y, dx, dy, d: INTEGER;
PROCEDURE Dot4(x1, x2, y1, y2, color, mode: INTEGER);
BEGIN
Display.DotC (f, color, x1, y1, mode);
Display.DotC (f, color, x1, y2, mode);
Display.DotC (f, color, x2, y1, mode);
Display.DotC (f, color, x2, y2, mode)
END Dot4;
BEGIN
x := r; y := 0; dx := 8*(x-1); dy := 8*y+4; d := 1-4*r;
WHILE x > y DO
Dot4(x0-x, x0+x, y0-y, y0+y, color, mode);
Dot4(x0-y, x0+y, y0-x, y0+x, color, mode);
INC(d, dy); INC(dy, 8); INC(y);
IF d >= 0 THEN DEC(d, dx); DEC(dx, 8); DEC(x) END
END;
IF x = y THEN Dot4(x0-x, x0+x, y0-y, y0+y, color, mode) END
END SCircle;
PROCEDURE SLine(f: Display.Frame; x1, y1, x2, y2, color, mode: INTEGER);
VAR x, y, dx, dy, d, inc: INTEGER;
BEGIN
IF (y2 - y1) < (x1 - x2) THEN x := x1; x1 := x2; x2 := x; y := y1; y1 := y2; y2 := y END;
dx := 2 * (x2 - x1);
dy := 2 * (y2 - y1);
x := x1; y := y1; inc := 1;
IF dy > dx THEN
d := dy DIV 2;
IF dx < 0 THEN inc := -1; dx := -dx END;
WHILE y <= y2 DO
Display.DotC (f, color, x, y, mode);
INC (y); DEC (d, dx);
IF d < 0 THEN INC (d, dy); INC (x, inc) END
END
ELSE
d := dx DIV 2;
IF dy < 0 THEN inc := -1; dy := -dy END;
WHILE x <= x2 DO
Display.DotC (f, color, x, y, mode);
INC (x); DEC (d, dy);
IF d < 0 THEN INC (d, dx); INC (y, inc) END
END
END
END SLine;
PROCEDURE PCircle (f: Display.Frame; x0, y0, r, color, mode: INTEGER);
BEGIN Printer.Circle (x0, y0, r)
END PCircle;
PROCEDURE PLine (f: Display.Frame; x1, y1, x2, y2, color, mode: INTEGER);
BEGIN Printer.Line (x1, y1, x2, y2)
END PLine;
(* view update *)
PROCEDURE Line2(f: Display.Frame; ang: INTEGER; x0, y0, r1, r2, color: INTEGER);
VAR x1, y1, x2, y2: INTEGER;
BEGIN
ang := (15-ang) MOD 60;
x1 := SHORT (ENTIER(r1 * cos[ang] + 0.5));
y1 := SHORT (ENTIER(r1 * sin[ang] + 0.5));
x2 := SHORT (ENTIER(r2 * cos[ang] + 0.5));
y2 := SHORT (ENTIER(r2 * sin[ang] + 0.5));
Line (f, x0 + x1, y0 + y1, x0 + x2, y0 + y2, color, Display.invert)
END Line2;
PROCEDURE Line3(f: Display.Frame; ang: INTEGER; x0, y0, r1, r2, color: INTEGER);
VAR x1, y1, x2, y2: INTEGER;
BEGIN
ang := (15-ang) MOD 60;
x1 := SHORT (ENTIER(r1 * cos[ang] + 0.5));
y1 := SHORT (ENTIER(r1 * sin[ang] + 0.5));
x2 := SHORT (ENTIER(r2 * cos[ang] + 0.5));
y2 := SHORT (ENTIER(r2 * sin[ang] + 0.5));
Line (f, x0 + x1, y0 + y1, x0 + x2, y0 + y2, color, Display.paint)
END Line3;
PROCEDURE (c: Item) Draw* (x, y: INTEGER; f: Display.Frame);
(** displays the object at (x, y) in frame f *)
VAR r, rh, rm, rs, i, sec, min, hour, hourm, mode, ox, oy, w, h: INTEGER;
BEGIN
Line := SLine; Circle := SCircle;
c.GetDim (ox, oy, w, h);
Display.ReplConstC (f, f(DialogFrames.Frame).col, x, y, w, h, Display.paint);
r := Min (w - 1 , h - 1) DIV 2; x := x + r; y := y + r;
IF c.selected THEN mode := Display.invert ELSE mode := Display.replace END;
IF r >= Rmin THEN
rh := 7 * r DIV 11; rm := 9 * r DIV 11; rs := 10 * r DIV 11; i := 0;
WHILE i < 60 DO Line3 (f, i, x, y, rm, r, black); INC (i, 5) END;
Format (DialogClocks.old.timeStamp, sec, min, hour, hourm);
Line2 (f, sec, x, y, rm-r, rs, black);
Line2 (f, min, x, y, 0, rm, black);
Line2 (f, hourm, x, y, 0, rh, black);
Circle (f, x, y, 2, black, mode)
END;
Circle(f, x, y, r, black, mode)
END Draw;
PROCEDURE (c: Item) Print* (x, y: INTEGER);
(** prints the object at printer coordinates (x, y) *)
VAR ox, oy, w, h, r, sec, min, hour, hourm, mode, i, rh, rm, rs: INTEGER; f: Display.Frame;
BEGIN
Line := PLine; Circle := PCircle;
c.GetPDim (ox, oy, w, h);
r := Min (w - 1 , h - 1) DIV 2; x := x + r; y := y + r;
IF r >= Rmin THEN
rh := 7 * r DIV 11; rm := 9 * r DIV 11; rs := 10 * r DIV 11; i := 0;
WHILE i < 60 DO Line2 (f, i, x, y, rm, r, black); INC (i, 5) END;
Format (DialogClocks.old.timeStamp, sec, min, hour, hourm);
Line2 (f, sec, x, y, rm-r, rs, black);
Line2 (f, min, x, y, 0, rm, black);
Line2 (f, hourm, x, y, 0, rh, black);
Circle (f, x, y, SHORT (2 * Dialogs.dUnit DIV Dialogs.pUnit), black, Display.paint)
END;
Circle(f, x, y, r, black, mode)
END Print;
PROCEDURE (c: Item) Redraw* (f: Display.Frame; x, y: INTEGER; old, new: DialogClocks.Time);
(** handles messages which were sent to frame f *)
VAR rh, rm, rs, olds, oldm, oldh, oldhm, news, newm, newh, newhm, ox, oy, w, h, r, mode: INTEGER;
BEGIN
c.GetDim (ox, oy, w, h);
r := Min (w - 1, h - 1) DIV 2; x := x + r; y := y + r;
IF c.selected THEN RETURN END;
Line := SLine; Circle := SCircle;
IF r >= Rmin THEN
rh := 7*r DIV 11; rm := 9*r DIV 11; rs := 10*r DIV 11;
Format (old.timeStamp, olds, oldm, oldh, oldhm); Format (new.timeStamp, news, newm, newh, newhm);
IF olds # news THEN Line2 (f, olds, x, y, rm-r, rs, black); Line2(f, news, x, y, rm-r, rs, black) END;
IF oldm # newm THEN Line2(f, oldm, x, y, 0, rm, black); Line2(f, newm, x, y, 0, rm, black) END;
IF oldhm # newhm THEN Line2(f, oldhm, x, y, 0, rh, black); Line2(f, newhm, x, y, 0, rh, black) END;
Circle (f, x, y, 2, black, mode)
END
END Redraw;
PROCEDURE (c: Item) Copy* (VAR dup: Dialogs.Object);
(** allocates dup and makes a deep copy of o. Before calling this methode dup should be equal NIL *)
VAR x: Item;
BEGIN
IF dup = NIL THEN NEW (x); dup := x ELSE x := dup(Item) END;
c.Copy^ (dup);
END Copy;
PROCEDURE Insert*;
(** Insert ([name] [x y w h] | ^ ) inserts a clock - item in the panel containing the caret position *)
VAR x, y, x1, y1, w, h: INTEGER; c: Item; p: Dialogs.Panel; name: ARRAY 64 OF CHAR;
BEGIN
NEW (c);
DialogFrames.GetCaretPosition (p, x, y);
IF (p # NIL) THEN
c.Init; In.Open; In.Name (name);
IF ~In.Done THEN COPY ("", name); In.Open END;
c.SetName (name);
In.Int (x1); In.Int (y1); In.Int (w); In.Int (h);
IF ~In.Done THEN x1 := x; y1 := y; w := W; h := H
ELSE
IF w < 0 THEN w := W END;
IF h < 0 THEN h := H END
END;
c.SetDim (x, y, W, H, FALSE); p.Insert (c, FALSE)
ELSE
Dialogs.res := Dialogs.noPanelSelected
END;
IF Dialogs.res # 0 THEN Dialogs.Error ("DialogClocks") END;
END Insert;
BEGIN Init
END DialogAnalogClocks.